package com.bridge.client.bridgedynamcclient.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.bridge.client.bridgedynamcclient.bean.ChoiceItem;
import com.bridge.client.bridgedynamcclient.bean.UrlConstant;
import com.bridge.client.bridgedynamcclient.bean.vo.resp.*;
import com.bridge.client.bridgedynamcclient.config.exception.BusException;
import com.bridge.client.bridgedynamcclient.consts.BridgeStatusEnum;
import com.bridge.client.bridgedynamcclient.utils.DataHelper;
import com.bridge.client.bridgedynamcclient.utils.FXMLUtil;
import com.bridge.client.bridgedynamcclient.utils.HttpUtil;
import com.bridge.client.bridgedynamcclient.utils.StringUtil;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.*;
import javafx.scene.control.skin.ChoiceBoxSkin;
import javafx.scene.layout.HBox;
import javafx.scene.text.Text;
import javafx.stage.Modality;
import javafx.stage.Stage;

import java.net.URL;
import java.util.*;

public class BridgeAddMainController extends BaseController implements Initializable {

    /**
     * 总模块
     */
    //桥梁名称
    @FXML
    private TextField tfBridgeName;
    //桥梁编码
    @FXML
    private TextField tfBridgeCode;
    //桥梁类型
    @FXML
    private ChoiceBox<ChoiceItem> choiceBridgeType;
    @FXML
    private Text bridgeTypeSample;
    //提交数据
    @FXML
    private Button btnSubmit;

    /**
     * 有限元模块
     */

    //桥跨数量
    @FXML
    private ChoiceBox<ChoiceItem> icCbMainSpanNumber;
    // 桥梁跨径布置 跨境个数容器
    @FXML
    private HBox icBoxSpanArrangementContain;

    //  立柱数量 容器
    @FXML
    private HBox icBoxColumnNumberContain;

    @FXML
    private TextField icTfColumnHeight;

    @FXML
    private TextField icTfBridgeWidth;

    //主梁材料类型
    @FXML
    private ChoiceBox<ChoiceItem> icCbBeamMaterialType;

    //主梁界面类型
    @FXML
    private ChoiceBox<ChoiceItem> icCbSingleBeamInterfaceType;

    //建设年代
    @FXML
    private TextField icTfConstructionYear;

    //加劲梁截面类型
    @FXML
    private ChoiceBox<ChoiceItem> icTfStiffeningGirderSectionType;
    //加劲梁材料类型
    @FXML
    private ChoiceBox<ChoiceItem> icTfStiffeningGirderMaterialType;

    //斜拉索面数
    @FXML
    private TextField icTfInclinedCableFaceNumber;
    //每面斜拉索数量
    @FXML
    private TextField icTfSingleSideFaceIncliendCableNumber;
    //主塔纵向形状
    @FXML
    private ChoiceBox<ChoiceItem> icCbMainTowerVerticalShape;
    //主塔横向形状
    @FXML
    private ChoiceBox<ChoiceItem> icCbMainTowerHorizontalShape;
    //主塔桥面上下部高度比
    @FXML
    private TextField icTfMainTowerFloorUpperLowerHeightRatio;
    //主塔桥面上部高度
    @FXML
    private TextField icTfMainTowerFloorUpperLowerHeight;

    //辅助墩数量
    @FXML
    private ChoiceBox<ChoiceItem> icCbAuxiliaryPierNumber;

    @FXML
    private Button icBtnWidthEvaluate;

    //跨径布置 估计
    @FXML
    private Button icBtnSpanArrangeEvaluate;

    //主塔高度 估计
    @FXML
    private Button icBtnTowerHeightEvaluate;

    //桥梁总长度
    @FXML
    private TextField icTfBridgeLength;

    /**
     * 神经网络 模块
     */
    //主跨跨径
    @FXML
    private TextField nnTfMainSpan;

    //主跨跨径识别
    @FXML
    private Button nnBtnMainSpanEvaluate;

    //主梁类型
    @FXML
    private ChoiceBox<ChoiceItem> nnCbMainBeamType;
    //梁桥类型
    @FXML
    private ChoiceBox<ChoiceItem> nnCbGirderType;
    //桥塔数量
    @FXML
    private TextField nnTfTowerNumber;
    //桥塔高度
    @FXML
    private TextField nnTfTowerHeight;



    /**
     * 数据分析
     */
    @FXML
    private ChoiceBox<ChoiceItem> maCbSampleType;
    //传感器采样频率
    @FXML
    private TextField maTfSensorSmaplingFrequency;
    //使用的测量样本的数量
    @FXML
    private TextField maTfMeasureSmapleNumber;

    //桥梁位置的EPSG代号
    @FXML
    private TextField maTfEpscCode;

    @FXML
    private Button maBtnChoiceSmaple;


    private Long recordId;

    private List<Long> sampleSelectIds=new ArrayList<>();

    private WidthParam widthParam;


    private boolean initOk=false;

    private String currentBridgeType;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {

        initListener();
    }


    private void initListener() {
        initBridgeTypeChoice();
        initTabPane();

        initCae();
        initPre();
        initMeasure();

        initBtnListener();
        initSample();

        initSubmitListener();
        initOk=true;
        //使用默认的配置
        setConfig( getDefaultData(1));

    }



    private void initBtnListener() {
        //宽度估计
        icBtnWidthEvaluate.setOnAction(a->{
            showWidthCalculateDialog();
        });
        //样本选择
        maBtnChoiceSmaple.setOnAction(a->{
            //请求 获取样本数据
            String bridgeCode = tfBridgeCode.getText();
            if(StringUtil.isEmpty(bridgeCode)){
                FXMLUtil.showAlertInfo("请先输入桥梁编码");
                return;
            }
            requestSampleList(bridgeCode);
        });

        //跨径布置估计
        icBtnSpanArrangeEvaluate.setOnAction(a->{
            String bridgeLength = icTfBridgeLength.getText();
            if(StringUtil.isEmpty(bridgeLength)){
                FXMLUtil.showAlertInfo("请先输入桥梁总长度");
                return;
            }
            resetMainSpanValue(icBoxSpanArrangementContain,getSpanValuesByBridgeLength(bridgeLength,icBoxSpanArrangementContain.getChildren().size()));
        });

        //主塔高度估计
        icBtnTowerHeightEvaluate.setOnAction(a->{
            List<String> spanValues = getSpanValues(icBoxSpanArrangementContain);
            if(spanValues==null){
                return;
            }

            icTfMainTowerFloorUpperLowerHeight.setText(getTowerFloorUpperHeight(spanValues));

        });

        //主跨跨径识别
        nnBtnMainSpanEvaluate.setOnAction(a->{
            String spanMax = getSpanMax();
            if(spanMax==null){
                return;
            }
            nnTfMainSpan.setText(spanMax);
        });
    }



    private void initCae() {
        initSpanNumber("1");
        initBeamMaterialType();
        initBeamInterfaceType();
        initStiffeningGirderMaterialType();
        //主塔形状
        initMainTowerShape();
        initAuxiliaryPierNumber();
    }

    private void initPre() {

        //主梁类型
        initMainBeamTypeChoice();
        //梁桥类型
        initGirderTypeChoice();

    }

    private void initMeasure() {
        //测试类型
        initSampleType();

        maTfMeasureSmapleNumber.setEditable(false);
    }


    private void initStiffeningGirderSectionType(String materialTYpe) {
        initChoiceType(icTfStiffeningGirderSectionType, DataHelper.getStiffeningGirderSectionTypeListByMaterialType(materialTYpe));
    }

    private void initStiffeningGirderMaterialType() {
        initChoiceType(icTfStiffeningGirderMaterialType, DataHelper.getStiffeningGirderMaterialTypeList(), new ChoiceBoxListener() {
            @Override
            public void onChoice(ChoiceItem item) {
                logger.info("联动 initStiffeningGirderMaterialType--onChoice:{}",item.getName());
                initStiffeningGirderSectionType(item.getValue());
            }
        });
    }

    private void initBeamInterfaceType() {
        initChoiceType(icCbSingleBeamInterfaceType, DataHelper.getSingleBeamInterfaceTypeList());
    }

    private void initBeamMaterialType() {
        initChoiceType(icCbBeamMaterialType, DataHelper.getMainMaterialTypeList());
    }

    private void initSpanNumber(String bridgeType) {
        initChoiceType(icCbMainSpanNumber, DataHelper.getMainSpanNumberList(bridgeType), new ChoiceBoxListener() {
            @Override
            public void onChoice(ChoiceItem item) {
                //logger.info("初始化 initMainSpan");
                if(item!=null){
                    initMainSpan(item.getValue());
                }
            }
        });

    }

    private void initAuxiliaryPierNumber() {
        initChoiceType(icCbAuxiliaryPierNumber, DataHelper.getAuxiliaryPierNumberList());
    }

    private void initSampleType() {
        initChoiceType(maCbSampleType, DataHelper.getSampleTypeList());
    }


    private void initSample() {
        //桥梁类型图例
        bridgeTypeSample.setOnMouseClicked(event -> {
            ChoiceItem value = choiceBridgeType.getValue();
            if (Objects.isNull(value)) {
                FXMLUtil.showAlertInfo("请先选择类型");
                return;
            }
            FXMLLoader loader = FXMLUtil.getLoader(BridgeAddMainController.class, "bridge-image-sample-view.fxml");
            FXMLUtil.loadView(loader, Modality.NONE, "图片示例");
            BridgeImageSampleController controller = loader.getController();
            List<ChoiceItem> items = new ArrayList<>();
            items.add(new ChoiceItem("图片1", "/images/iamge1.jpg"));
            items.add(new ChoiceItem("图片2", "/images/iamge2.jpg"));
            controller.setConfig(items);
        });
    }


    private void initSubmitListener() {

        btnSubmit.setOnAction(a -> {
            //需要根据桥梁类型构建不同的参数
            // Map<String,Object> params= buildParam();
            sendAddRequest();

        });
    }

    private void sendAddRequest() {

        try {
            btnSubmit.setDisable(true);
            buildParam();
        } catch (Exception e) {
            if (e instanceof BusException) {
                FXMLUtil.showAlertInfo(e.getMessage());
            }
        }finally {
            btnSubmit.setDisable(false);
        }
    }

    private void buildParam() throws BusException {
        Map<String, Object> params = new HashMap<>();

        if (Objects.nonNull(recordId)) {
            params.put("recordId", recordId);
        }
        ChoiceItem bridgeType = choiceBridgeType.getValue();
        //桥梁名称
        addTextFieldParam(params, "bridgeName", tfBridgeName, "请输入桥梁名称");
        //桥梁编码
        addTextFieldParam(params, "bridgeCode", tfBridgeCode, "桥梁编码 未输入");
        //桥梁类型
        addChoiceParam(params, "bridgeType", choiceBridgeType, "请选择桥梁类型");

        //有限元 参数集合
        Map<String, Object> paramsIc = new HashMap<>();
        //网络神经 参数集合
        Map<String, Object> paramsNn = new HashMap<>();
        //数据分析 参数集合
        Map<String, Object> paramsMa = new HashMap<>();

        params.put("identifyCae", paramsIc);
        params.put("neuralNetwork", paramsNn);
        params.put("monitorAnalysis", paramsMa);


        //有限元参数
        buildParamIcModelByBridgeType(paramsIc, bridgeType.getValue());

        //神经网络参数
        buildParamNnModelByBridgeType(paramsNn, bridgeType.getValue());
        //车载动力
        buildParamMaModelByBridgeType(paramsMa, bridgeType.getValue());


        postAddBridge(params);



    }


    private void addSpanParam(Map<String, Object> map, String key, HBox box, String tips) throws BusException {
        ObservableList<Node> spanArrangementChild = box.getChildren();
        if (spanArrangementChild.isEmpty()) {
            throw new BusException(tips);
        }
        boolean isOk = true;
        List<String> mainSpanList = new ArrayList<>();
        for (Node node : spanArrangementChild) {
            if (node instanceof TextField) {
                String span = ((TextField) node).getText();
                if (StringUtil.isEmpty(span)) {
                    isOk = false;
                    break;
                }
                mainSpanList.add(span);
            }
        }
        if (!isOk) {
            throw new BusException("跨径布置 未输入");
        }
        map.put(key, mainSpanList.toString());
    }



    private List<String> getSpanValues(HBox box){
        ObservableList<Node> spanArrangementChild = box.getChildren();
        if (spanArrangementChild.isEmpty()) {
            FXMLUtil.showAlertInfo("未配置跨径布置");
            return null;
        }
        boolean isOk = true;
        List<String> mainSpanList = new ArrayList<>();
        for (Node node : spanArrangementChild) {
            if (node instanceof TextField) {
                String span = ((TextField) node).getText();
                if (StringUtil.isEmpty(span)) {
                    isOk = false;
                    break;
                }
                mainSpanList.add(span);
            }
        }
        if (!isOk) {
            FXMLUtil.showAlertInfo("跨径布置 未输入");
            return null;
        }
        return mainSpanList;
    }

    private void addTextFieldParam(Map<String, Object> map, String key, TextField textField, String showDialogInfo) throws BusException {
        addTextFieldParam(map, key, textField, showDialogInfo, true);
    }

    private void addTextFieldParam(Map<String, Object> map, String key, TextField textField, String showDialogInfo, boolean necessary) throws BusException {
        String value = textField.getText();
        if (StringUtil.isEmpty(value)) {
            if (necessary) {
                throw new BusException(showDialogInfo);
            }
            return;
        }
        map.put(key, value);
    }

    private void addChoiceParam(Map<String, Object> map, String key, ChoiceBox<ChoiceItem> choiceBox, String showDialogInfo) throws BusException {
        addChoiceParam(map, key, choiceBox, showDialogInfo, true);

    }

    private void addChoiceParam(Map<String, Object> map, String key, ChoiceBox<ChoiceItem> choiceBox, String showDialogInfo, boolean necessary) throws BusException {
        ChoiceItem value = choiceBox.getValue();
        if (Objects.isNull(value)) {
            if (necessary) {
                throw new BusException(showDialogInfo);
            }
        }
        map.put(key, value.getValue());

    }


    private void initMainTowerShape() {
        initChoiceType(icCbMainTowerVerticalShape, DataHelper.getMainTowerVerticalShapeList());

        initChoiceType(icCbMainTowerHorizontalShape, DataHelper.getMainTowerHorizontalShapeList());

    }


    //桥梁跨径布置
    private void initMainSpan(String number) {
        Integer numberInt=Integer.valueOf(number);
        if(icBoxSpanArrangementContain.getChildren().size()!=numberInt){
            logger.info("初始化 initMainSpan，数量：{},条目数量：{}",number,icBoxSpanArrangementContain.getChildren().size());
            changeSpanArrangementContain(icBoxSpanArrangementContain, numberInt,null);
        }
        if((icBoxColumnNumberContain.getChildren().size()-1)!=numberInt){
            changeSpanArrangementContain(icBoxColumnNumberContain, numberInt+1,"1");
        }
    }


    private void resetMainSpanValue(HBox contain,List<String> newValues) {
        if(contain.getChildren().size()!=newValues.size()){
            FXMLUtil.showAlertInfo("数量不对等");
            return;
        }
        for (int i = 0; i < contain.getChildren().size(); i++) {
            Node node = contain.getChildren().get(i);
            if(node instanceof TextField){
                ((TextField) node).setText(newValues.get(i));
            }
        }
    }

    private List<String> getSpanValuesByBridgeLength(String bridgeLength,int size) {
        List<String> values=new ArrayList<>();
        double lengthDouble=Double.valueOf(bridgeLength);
        if(currentBridgeType.equals("1")){
            //梁桥  均分
            String value=String.format("%.2f",lengthDouble/size);
            for (int i = 0; i < size; i++) {
                values.add(value);
            }
        }else if(currentBridgeType.equals("3")){
            //斜拉桥  数量 =2的话0.5：1分，>2的话 头和尾 各0.4，中间均分
            if(size==2){
                values.add(String.format("%.2f", lengthDouble * (0.5 / 1.5)));
                values.add(String.format("%.2f", lengthDouble * (1 / 1.5)));
            }else {
                double total = 0.4 * 2 + (size - 2) * 1;
                for (int i=0;i<size;i++){
                    if (i == 0 || i == (size - 1)) {
                        values.add(String.format("%.2f",lengthDouble * (0.4 / total)));
                    } else {
                        values.add(String.format("%.2f", lengthDouble * (1 / total)));
                    }
                }
            }
        }
        return values;
    }

    private void changeSpanArrangementContain(HBox contain, Integer number,String defaultValue) {
        ObservableList<Node> children = contain.getChildren();
        if (children.size() == number) {
            return;
        }
        //移除 之前的。再重新添加
        contain.getChildren().clear();
        for (Integer i = 0; i < number; i++) {
            TextField ftSpanArrangement = new TextField();
            ftSpanArrangement.setPrefHeight(32);
            ftSpanArrangement.setPrefWidth(45);
            if(!StringUtil.isEmpty(defaultValue)){
                ftSpanArrangement.setText(defaultValue);
            }
            contain.getChildren().add(ftSpanArrangement);
        }

    }


    private void initTabPane() {

    }

    private void initBridgeTypeChoice() {
        initChoiceType(choiceBridgeType, DataHelper.getBridgeTypeList(), new ChoiceBoxListener() {
            @Override
            public void onChoice(ChoiceItem item) {
                if(StringUtil.equals(item.getValue(),currentBridgeType)){
                    return;
                }
                currentBridgeType=item.getValue();
                dealViewShowStateByBridgeType(item.getValue());
                if(initOk&&recordId ==null){
                    //使用默认的配置
                    setConfig( getDefaultData(Integer.valueOf(item.getValue())));
                }

            }
        });

    }


    private void initChoiceType(ChoiceBox<ChoiceItem> choiceBox, ObservableList<ChoiceItem> items) {
        initChoiceType(choiceBox, items, null);
    }

    private void initChoiceType(ChoiceBox<ChoiceItem> choiceBox, ObservableList<ChoiceItem> items, ChoiceBoxListener listener) {

        choiceBox.setOnAction(null);

        choiceBox.setItems(items);

        choiceBox.setSelectionModel(new SingleSelectionModel<ChoiceItem>() {
            @Override
            protected ChoiceItem getModelItem(int i) {
                if (i < 0) {
                    return null;
                }
                return items.get(i);
            }

            @Override
            protected int getItemCount() {
                return items.size();
            }
        });
        choiceBox.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent actionEvent) {
                if (null != listener) {
                    listener.onChoice(choiceBox.getValue());
                }
            }
        });
        //默认选第一个
        choiceBox.getSelectionModel().select(0);

        // 设置CSS，修改下拉菜单的长度
        String css = """
            .choice-box .list-view {
                -fx-pref-height: 100; /* 设置下拉菜单的高度 */
            }
            .choice-box .list-cell {
                -fx-pref-width: 200; /* 设置下拉菜单中每个项的宽度 */
            }
                .choice-box .context-menu {
                    -fx-pref-width: 220; /* Your width for the context menu background shown */
                }
            """;
//        choiceBox.getScene().getStylesheets().add(css);
//        choiceBox.setOnShowing(new EventHandler<Event>() {
//            @Override
//            public void handle(Event event) {
//
//            }
//        });
        // 在 ChoiceBox 显示时动态调整下拉宽度
//        choiceBox.setOnShown(event -> {
//            logger.info("setOnShown---1");
//            Node popup = choiceBox.lookup(".choice-box .list-view");
//            logger.info("setOnShown---1--:"+popup.getClass().getSimpleName());
//            if (popup instanceof ListView) {
//                logger.info("setOnShown---2");
//                ListView<?> listView = (ListView<?>) popup;
//                // 绑定下拉宽度到 ChoiceBox 的宽度
//                listView.prefWidthProperty().bind(choiceBox.widthProperty());
//            }
//        });
        //setChoiceBoxDropdownWidth(choiceBox,choiceBox.getPrefWidth());
    }
    /**
     * 设置 ChoiceBox 下拉菜单的宽度
     * @param choiceBox 要设置的 ChoiceBox
     * @param width 下拉菜单的宽度
     */
    private void setChoiceBoxDropdownWidth(ChoiceBox<?> choiceBox, double width) {
        // 当 ChoiceBox 显示时执行设置宽度的操作
        choiceBox.showingProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue) {
                // 获取 ChoiceBox 的皮肤
                ChoiceBoxSkin<?> skin = (ChoiceBoxSkin<?>) choiceBox.getSkin();
                logger.info("skin:"+skin.getChildren().get(0).getClass().getSimpleName());
//                // 从皮肤中获取下拉列表
//                ListView<?> listView = (ListView<?>) skin.getNode();
//                // 设置下拉列表的宽度
//                listView.setPrefWidth(width);
                skin.getChildren().forEach(child->{
                    logger.info("skin:"+child.getClass().getSimpleName());
                });
            }
        });
    }

    private interface ChoiceBoxListener {
        void onChoice(ChoiceItem item);
    }

    private void initMainBeamTypeChoice() {

        initChoiceType(nnCbMainBeamType,DataHelper.getMainBeamTypeList());

    }


    private void initGirderTypeChoice() {
        initChoiceType(nnCbGirderType, DataHelper.getGirderTypeList());

    }

    private void dealViewShowStateByBridgeType(String bridgeType) {
        /**
         * 1-梁桥 2-拱桥  3-斜拉桥  4-悬索桥
         */
        dealViewShowStateIcModelByBridgeType(bridgeType);
        dealViewShowStateNnModelByBridgeType(bridgeType);
        dealViewShowStateMaModelByBridgeType(bridgeType);

    }

    /**
     * 有限元
     *
     * @param bridgeType
     */
    private void dealViewShowStateIcModelByBridgeType(String bridgeType) {


        hideView(icBoxColumnNumberContain.getParent());
        hideView(icTfColumnHeight.getParent());
        hideView(icCbBeamMaterialType.getParent());
        hideView(icCbSingleBeamInterfaceType.getParent());

        hideView(icTfStiffeningGirderSectionType.getParent());
        hideView(icTfStiffeningGirderMaterialType.getParent());
        hideView(icTfInclinedCableFaceNumber.getParent());
        hideView(icTfSingleSideFaceIncliendCableNumber.getParent());
        hideView(icCbMainTowerVerticalShape.getParent());
        hideView(icCbMainTowerHorizontalShape.getParent());
        hideView(icTfMainTowerFloorUpperLowerHeightRatio.getParent());
        hideView(icTfMainTowerFloorUpperLowerHeight.getParent());
        hideView(icCbAuxiliaryPierNumber.getParent());

        if (bridgeType.equals("1")) {
            showView(icCbBeamMaterialType.getParent());
            showView(icCbSingleBeamInterfaceType.getParent());
            showView(icBoxColumnNumberContain.getParent());
            showView(icTfColumnHeight.getParent());
        } else if (bridgeType.equals("3")) {

            showView(icTfStiffeningGirderSectionType.getParent());
            showView(icTfStiffeningGirderMaterialType.getParent());
            showView(icTfInclinedCableFaceNumber.getParent());
            showView(icTfSingleSideFaceIncliendCableNumber.getParent());
            showView(icCbMainTowerVerticalShape.getParent());
            showView(icCbMainTowerHorizontalShape.getParent());
            showView(icTfMainTowerFloorUpperLowerHeightRatio.getParent());
            showView(icTfMainTowerFloorUpperLowerHeight.getParent());
            showView(icCbAuxiliaryPierNumber.getParent());
        }
        logger.info("初始化 initMainSpan 数据源有变动");
        initSpanNumber(bridgeType);
//        ChoiceItem currentItem = icCbMainSpanNumber.getValue();
//        icCbMainSpanNumber.setItems(DataHelper.getMainSpanNumberList(bridgeType));
        //if()

    }

    /**
     * 神经网络
     *
     * @param bridgeType
     */
    private void dealViewShowStateNnModelByBridgeType(String bridgeType) {

        hideView(nnCbGirderType.getParent());

        hideView(nnCbMainBeamType.getParent());
        hideView(nnTfTowerNumber.getParent());
        hideView(nnTfTowerHeight.getParent());

        if (bridgeType.equals("1")) {

            showView(nnCbGirderType.getParent());
        } else if (bridgeType.equals("3")) {
            showView(nnCbMainBeamType.getParent());
            showView(nnTfTowerNumber.getParent());
            showView(nnTfTowerHeight.getParent());
        }
    }

    /**
     * 数据分析模块
     *
     * @param bridgeType
     */
    private void dealViewShowStateMaModelByBridgeType(String bridgeType) {


    }

    /**
     * 有限元
     *
     * @param bridgeType
     */
    private void buildParamIcModelByBridgeType(Map<String, Object> paramIc, String bridgeType) throws BusException {
        addTextFieldParam(paramIc, "bridgeLength", icTfBridgeLength, "请输入 桥梁总长度");
        //跨径布置
        addSpanParam(paramIc, "spanArrangement", icBoxSpanArrangementContain, "请设置跨径");
        //桥梁宽度
        addTextFieldParam(paramIc, "bridgeWidth", icTfBridgeWidth, "请输入 桥梁宽度");
        //建年年代
        addTextFieldParam(paramIc, "constructionYear", icTfConstructionYear, "建设年代", false);

        if (bridgeType.equals("1")) {
            addSpanParam(paramIc, "columnNumSpan", icBoxColumnNumberContain, "请设置立柱");
            addTextFieldParam(paramIc, "columnHeight", icTfColumnHeight, "请输入 立柱高度",false);
            addChoiceParam(paramIc, "mainMaterialType", icCbBeamMaterialType, "主梁材料类型");
            addChoiceParam(paramIc, "singleBeamInterfaceType", icCbSingleBeamInterfaceType, "主梁截面类型", false);

        } else if (bridgeType.equals("3")) {
            addChoiceParam(paramIc, "stiffeningGirderMaterialType", icTfStiffeningGirderMaterialType, "");
            addChoiceParam(paramIc, "stiffeningGirderSectionType", icTfStiffeningGirderSectionType, "");
            addTextFieldParam(paramIc, "inclinedCableFaceNumber", icTfInclinedCableFaceNumber, "斜拉索面数");
            addTextFieldParam(paramIc, "singleSideFaceInclinedCableNumber", icTfSingleSideFaceIncliendCableNumber, "每面斜拉索数量");
            addChoiceParam(paramIc, "mainTowerVerticalShape", icCbMainTowerVerticalShape, "主塔纵向形状");
            addChoiceParam(paramIc, "mainTowerHorizontalShape", icCbMainTowerHorizontalShape, "主塔横向形状");
            addTextFieldParam(paramIc, "mainTowerFloorUpperLowerHeightRatio", icTfMainTowerFloorUpperLowerHeightRatio, "主塔桥面上下部高度比");
            addTextFieldParam(paramIc, "mainTowerFloorUpperHeight", icTfMainTowerFloorUpperLowerHeight, "主塔桥面上部高度");
            addChoiceParam(paramIc, "auxiliaryPierNumber", icCbAuxiliaryPierNumber, "辅助墩数量");
        }
    }

    /**
     * 神经网络
     *
     * @param bridgeType
     */
    private void buildParamNnModelByBridgeType(Map<String, Object> paramNn, String bridgeType) throws BusException {
        addTextFieldParam(paramNn, "mainSpan", nnTfMainSpan, "主跨跨径");


        if (bridgeType.equals("1")) {
            addChoiceParam(paramNn, "girderType", nnCbGirderType, "梁桥类型");

        } else if (bridgeType.equals("3")) {
            addChoiceParam(paramNn, "mainBeamType", nnCbMainBeamType, "主梁类型");
            addTextFieldParam(paramNn, "towerNumber", nnTfTowerNumber, "桥塔数量");
            addTextFieldParam(paramNn, "towerHeight", nnTfTowerHeight, "桥塔高度");
        }
    }

    /**
     * 车载动力
     *
     * @param bridgeType
     */
    private void buildParamMaModelByBridgeType(Map<String, Object> paramMa, String bridgeType) throws BusException {
        addChoiceParam(paramMa, "sampleType", maCbSampleType, "测试类型");
        addTextFieldParam(paramMa, "sensorSamplingFrequency", maTfSensorSmaplingFrequency, "采样频率");
        addTextFieldParam(paramMa, "measurementSampleNumber", maTfMeasureSmapleNumber, "样本数量");
        paramMa.put("measurementSampleIds", sampleSelectIds.toString());
        addTextFieldParam(paramMa, "epscCode", maTfEpscCode, "桥梁EPSG代号");
    }


    private void showView(Parent parent) {
        parent.setVisible(true);
        parent.setManaged(true);
    }

    private void hideView(Parent parent) {
        parent.setVisible(false);
        parent.setManaged(false);
    }

    public void setConfig(BridgeRecordData.BridgeRecord bridgeRecord) {
        setConfig(bridgeRecord,true);
    }

    public void setConfigByRequestDetail(BridgeRecordData.BridgeRecord bridgeRecord,boolean fromEditable){
        requestBridgeDetail(bridgeRecord.getRecordId(),fromEditable);
    }
    public void setConfig(BridgeRecordData.BridgeRecord bridgeRecord,boolean fromEditable) {
        recordId = bridgeRecord.getRecordId();
        //text控件是否可编辑
        boolean editable = !bridgeRecord.getResultStatus().equals(BridgeStatusEnum.FINISH.getCode())&&fromEditable;
        //选择控件 是否 不可用
        boolean disable = bridgeRecord.getResultStatus().equals(BridgeStatusEnum.FINISH.getCode())||!fromEditable;
        //桥梁名称
        dealTextField(tfBridgeName, bridgeRecord.getBridgeName(), editable);

        dealTextField(tfBridgeCode, bridgeRecord.getBridgeCode(), editable);
        //桥梁类型
        dealChoiceSelect(choiceBridgeType, false, bridgeRecord.getBridgeType().toString(), disable);

        //有限元模块
        //桥梁跨径布置
        IdentifyCaeData identifyCae = bridgeRecord.getIdentifyCae();
        //总长度
        dealTextField(icTfBridgeLength,identifyCae.getBridgeLength(),editable);
        //跨径，需要再单独处理
        logger.info("初始化 initMainSpan 设置跨径数据,data:{}",identifyCae.getSpanArrangement());
        dealArrangement(identifyCae.getSpanArrangement(), icBoxSpanArrangementContain, icCbMainSpanNumber, disable);
        //立柱数量
        dealArrangement(identifyCae.getColumnNumSpan(), icBoxColumnNumberContain, null, disable);
        //立柱高度
        dealTextField(icTfColumnHeight,identifyCae.getColumnHeight(),editable);
        //桥梁宽度
        dealTextField(icTfBridgeWidth, identifyCae.getBridgeWidth(), editable);
        //主梁材料类型
        dealChoiceSelect(icCbBeamMaterialType, false, identifyCae.getMainMaterialType(), disable);
        //主梁截面界面类型
        dealChoiceSelect(icCbSingleBeamInterfaceType, false, identifyCae.getSingleBeamInterfaceType(), disable);
        //建设年代
        dealTextField(icTfConstructionYear, identifyCae.getConstructionYear(), editable);


        //加劲梁材料类型
        logger.info("联动 初始化材料类型");
        dealChoiceSelect(icTfStiffeningGirderMaterialType, false, identifyCae.getStiffeningGirderMaterialType(), disable);

        //加劲梁截面类型
        logger.info("联动 初始化截面类型");
        dealChoiceSelect(icTfStiffeningGirderSectionType, false, identifyCae.getStiffeningGirderSectionType(), disable);

        //斜拉索面数
        dealTextField(icTfInclinedCableFaceNumber, identifyCae.getInclinedCableFaceNumber(), editable);
        //单边单面斜拉索数量
        dealTextField(icTfSingleSideFaceIncliendCableNumber, identifyCae.getSingleSideFaceInclinedCableNumber(), editable);
        //主塔形状
        dealChoiceSelect(icCbMainTowerVerticalShape, false, identifyCae.getMainTowerVerticalShape(), disable);
        dealChoiceSelect(icCbMainTowerHorizontalShape, false, identifyCae.getMainTowerHorizontalShape(), disable);
        //主塔桥面上下部高度比
        dealTextField(icTfMainTowerFloorUpperLowerHeightRatio, identifyCae.getMainTowerFloorUpperLowerHeightRatio(), editable);
        //主塔桥面上部高度
        dealTextField(icTfMainTowerFloorUpperLowerHeight, identifyCae.getMainTowerFloorUpperHeight(), editable);
        //辅助墩数量
        dealChoiceSelect(icCbAuxiliaryPierNumber, false, identifyCae.getAuxiliaryPierNumber(), disable);


        //神经网络模块
        NeuralNetworkData neuralNetwork = bridgeRecord.getNeuralNetwork();

        //梁桥类型
        dealChoiceSelect(nnCbGirderType, false, neuralNetwork.getGirderType(), disable);
        //主跨跨径
        dealTextField(nnTfMainSpan, neuralNetwork.getMainSpan(), editable);
        //主梁类型
        dealChoiceSelect(nnCbMainBeamType, false, neuralNetwork.getMainBeamType(), disable);
        //桥塔数量
        dealTextField(nnTfTowerNumber, neuralNetwork.getTowerNumber(), editable);
        //桥塔高度
        dealTextField(nnTfTowerHeight, neuralNetwork.getTowerHeight(), editable);

        //数据分析
        MonitorAnalysisData monitorAnalysis = bridgeRecord.getMonitorAnalysis();
        //测试类型
        dealChoiceSelect(maCbSampleType, false, monitorAnalysis.getSampleType().toString(), disable);
        //传感器采样频率
        dealTextField(maTfSensorSmaplingFrequency, monitorAnalysis.getSensorSamplingFrequency(), editable);
        //使用的测量样本的数量
        resetSelectIds(monitorAnalysis.getMeasurementSampleIds());
        maTfMeasureSmapleNumber.setEditable(false);
        //桥梁位置的EPSG代号
        dealTextField(maTfEpscCode, monitorAnalysis.getEpscCode(), editable);


        if(recordId!=null){
            btnSubmit.setDisable(disable);

            icBtnWidthEvaluate.setDisable(disable);
            maBtnChoiceSmaple.setDisable(disable);
            icBtnSpanArrangeEvaluate.setDisable(disable);
            icBtnTowerHeightEvaluate.setDisable(disable);
            nnBtnMainSpanEvaluate.setDisable(disable);


            //桥梁类型 不允许变更了
            choiceBridgeType.setDisable(true);
            tfBridgeCode.setEditable(false);
        }else {
            btnSubmit.setDisable(false);

            icBtnWidthEvaluate.setDisable(false);
            maBtnChoiceSmaple.setDisable(false);
            icBtnSpanArrangeEvaluate.setDisable(false);
            icBtnTowerHeightEvaluate.setDisable(false);
            nnBtnMainSpanEvaluate.setDisable(false);


            //桥梁类型 不允许变更了
            choiceBridgeType.setDisable(false);
            tfBridgeCode.setEditable(true);
        }
    }

    private BridgeRecordData.BridgeRecord getDefaultData(Integer bridgeType) {
        BridgeRecordData.BridgeRecord bridgeRecord=new BridgeRecordData.BridgeRecord();
        //默认梁桥
        bridgeRecord.setBridgeType(bridgeType);
        bridgeRecord.setResultStatus(0);
        //有限元
        IdentifyCaeData identifyCaeData = new IdentifyCaeData();
        if(bridgeType==1){
            identifyCaeData.setSpanArrangement("[45]");
            identifyCaeData.setColumnNumSpan("[1,2]");
            identifyCaeData.setColumnHeight("45");
            identifyCaeData.setBridgeWidth("25.5");
            identifyCaeData.setBridgeLength("45");
            identifyCaeData.setMainMaterialType("1");
            identifyCaeData.setSingleBeamInterfaceType("2");
            identifyCaeData.setConstructionYear("2000");
        }else if(bridgeType==3){
            identifyCaeData.setBridgeWidth("25");
            identifyCaeData.setBridgeLength("1100");
            identifyCaeData.setSpanArrangement("[243,602,243]");
            identifyCaeData.setConstructionYear("2000");
            identifyCaeData.setStiffeningGirderMaterialType("3");
            identifyCaeData.setStiffeningGirderSectionType("3");
            identifyCaeData.setInclinedCableFaceNumber("2");
            identifyCaeData.setSingleSideFaceInclinedCableNumber("31");
            identifyCaeData.setMainTowerVerticalShape("1");
            identifyCaeData.setMainTowerHorizontalShape("2");
            identifyCaeData.setMainTowerFloorUpperLowerHeightRatio("3");
            identifyCaeData.setMainTowerFloorUpperHeight("170.0");
            identifyCaeData.setAuxiliaryPierNumber("1");

        }

        bridgeRecord.setIdentifyCae(identifyCaeData);
        //预评估模型
        NeuralNetworkData neuralNetworkData = new NeuralNetworkData();
        if(bridgeType==1){
            neuralNetworkData.setGirderType("1");
            neuralNetworkData.setMainSpan("45");
        }else if(bridgeType==3){
            neuralNetworkData.setMainSpan("602");
            neuralNetworkData.setMainBeamType("钢混组合梁");
            neuralNetworkData.setTowerNumber("2");
            neuralNetworkData.setTowerHeight("220");
        }

        bridgeRecord.setNeuralNetwork(neuralNetworkData);
        //车载动力分析
        MonitorAnalysisData monitorAnalysisData = new MonitorAnalysisData();
        monitorAnalysisData.setSampleType(0);
        monitorAnalysisData.setEpscCode("32651");
        monitorAnalysisData.setSensorSamplingFrequency("100");
        monitorAnalysisData.setMeasurementSampleIds("[]");
        bridgeRecord.setMonitorAnalysis(monitorAnalysisData);


        return bridgeRecord;
    }

    private void dealCheckBox(CheckBox cb, String value, boolean disable) {
        if (StringUtil.isEmpty(value)) {
            return;
        }
        //默认 1是选择 0是未选择
        cb.setSelected(value.equals("1"));
        cb.setDisable(disable);
    }

    private void dealTextField(TextField tf, String value, boolean editable) {
        if (StringUtil.isEmpty(value)) {
            return;
        }
        tf.setText(value);
        tf.setEditable(editable);
    }

    private void dealArrangement(String listStr, HBox hBox, ChoiceBox<ChoiceItem> relationChoiceBox, boolean disable) {
        if (StringUtil.isEmpty(listStr)) {
            return;
        }
        List<String> list = JSON.parseArray(listStr, String.class);
        //先初始化 这个
        if(relationChoiceBox!=null){
            dealChoiceSelect(relationChoiceBox,false,String.valueOf(list.size()),disable);
        }

        //再去处理 跨径布置的问题
        ObservableList<Node> childrens = hBox.getChildren();
        for (int i = 0; i < childrens.size(); i++) {
            Node child = childrens.get(i);
            if(child instanceof TextField){
                ((TextField) child).setText(list.get(i));
                ((TextField) child).setEditable(!disable);
            }
        }
    }

    private void dealChoiceSelect(ChoiceBox<ChoiceItem> cb, boolean equalsName, String equalsValue, boolean disable) {
        if (StringUtil.isEmpty(equalsValue)) {
            return;
        }
        ObservableList<ChoiceItem> items = cb.getItems();
        if (items.isEmpty()) {
            return;
        }
        int index = 0;
        for (int i = 0; i < items.size(); i++) {
            if (equalsName) {
                if (items.get(i).getName().equals(equalsValue)) {
                    index = i;
                    break;
                }
            } else {
                if (items.get(i).getValue().equals(equalsValue)) {
                    index = i;
                    break;
                }
            }

        }
        cb.getSelectionModel().select(index);
        cb.setDisable(disable);
    }

    private void resetSelectIds(String strIds){
        sampleSelectIds.clear();
        if(!StringUtil.isEmpty(strIds)){
            sampleSelectIds.addAll(JSON.parseArray(strIds,Long.class));
        }
        maTfMeasureSmapleNumber.setText(String.valueOf(sampleSelectIds.size()));
    }


    private void postAddBridge(Map<String, Object> params) {
        BaseResp baseResp = HttpUtil.postBodyProxy(UrlConstant.bridgeAdd, params, BaseResp.class);
        if (Objects.isNull(baseResp)) {
            return;
        }
        if (!baseResp.isSuccess()) {
            FXMLUtil.showAlertInfo(baseResp.getMessage());
            return;
        }
        if(recordId==null){
            //跳转下一个页面
            FXMLLoader loader = FXMLUtil.getLoader(getClass(), "bridge-add-success-view.fxml");
            FXMLUtil.loadView(loader);

        }
        //当前页面 关闭
        FXMLUtil.closeState(root.getScene());
    }

    private void requestSampleList(String bridgeCode) {
        new Thread(new Runnable() {
            @Override
            public void run() {

                Map<String, Object> params = new HashMap<>();
                params.put("bridgeCode", bridgeCode);
                params.put("sampleType", maCbSampleType.getValue().getValue());
                String postedBody = HttpUtil.postBody(UrlConstant.bridgeSampleList, params, null);
                BaseResp<BridgeSampleData> baseResp = JSON.parseObject(postedBody, new TypeReference<BaseResp<BridgeSampleData>>() {
                });

                if (baseResp == null || !baseResp.isSuccess()) {
                    logger.info("requestSampleList = 请求数据失败，参数：param:{}", params.toString());
                    return;
                }
                logger.info("requestSampleList = 请求数据成功，result:{}", JSON.toJSONString(baseResp));
                BridgeSampleData data = baseResp.getData();

                //主线程 弹框提示
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        if(data.getBodyList().isEmpty()){
                            FXMLUtil.showAlertInfo("没有样本数据");
                        }else {
                            showSampleSelectDialog(data.getBodyList());
                        }

                    }
                });
            }
        }).start();
    }


    private void requestBridgeDetail(Long recordId,boolean fromEditable) {
        new Thread(new Runnable() {
            @Override
            public void run() {

                Map<String, Object> params = new HashMap<>();
                params.put("recordId", recordId);
                String postedBody = HttpUtil.postBody(UrlConstant.bridgeDetail, params, null);
                BaseResp<BridgeRecordData.BridgeRecord> baseResp = JSON.parseObject(postedBody, new TypeReference<BaseResp<BridgeRecordData.BridgeRecord>>() {
                });

                if (baseResp == null || !baseResp.isSuccess()) {
                    logger.info("requestBridgeDetail = 请求数据失败，参数：param:{}", params.toString());
                    return;
                }
                logger.info("requestBridgeDetail = 请求数据成功，result:{}", JSON.toJSONString(baseResp));
                BridgeRecordData.BridgeRecord data = baseResp.getData();

                //主线程 刷新数据
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        setConfig(data,fromEditable);
                    }
                });
            }
        }).start();
    }

    private void showSampleSelectDialog(List<BridgeSampleData.BridgeSample> bodyList) {
        //跳转下一个页面
        FXMLLoader loader = FXMLUtil.getLoader(getClass(), "bridge-sample-select-view.fxml");
        FXMLUtil.loadView(loader,Modality.APPLICATION_MODAL,"样本选择");
        BridgeSampleSelectController controller=loader.getController();
        controller.setConfig(bodyList,sampleSelectIds,this);
    }

    private void showWidthCalculateDialog(){
        //跳转下一个页面
        FXMLLoader loader = FXMLUtil.getLoader(getClass(), "bridge-width-calculate-view.fxml");
        FXMLUtil.loadView(loader,Modality.APPLICATION_MODAL,"宽度估计");
        BridgeWidthCalculateController controller=loader.getController();
        controller.setConfig(widthParam,this);
    }

    //回调的接口  选择完成了样本后
    protected void onSampleSelect(List<Long> ids){
        sampleSelectIds.clear();
        sampleSelectIds.addAll(ids);
        maTfMeasureSmapleNumber.setText(String.valueOf(sampleSelectIds.size()));
    }

    //回调的接口 宽度估计
    protected void onBridgeWidthCalculate(String result,WidthParam widthParam){
        icTfBridgeWidth.setText(result);
        this.widthParam=widthParam;
    }


    private String getTowerFloorUpperHeight(List<String> spanValues) {
        double max=0.0;
        for (String spanValue : spanValues) {
            if(Double.valueOf(spanValue)>max){
                max=Double.valueOf(spanValue);
            }
        }
        return String.format("%.2f", max / 3.6);
    }

    private String getSpanMax(){
        List<String> spanValues = getSpanValues(icBoxSpanArrangementContain);
        if(spanValues==null){
            return null;
        }
        double max=0.0;
        for (String spanValue : spanValues) {
            if(Double.valueOf(spanValue)>max){
                max=Double.valueOf(spanValue);
            }
        }

        return String.valueOf(max);
    }


    public static class WidthParam{
        private String motorWayNumber;
        private String nonMotorWayNumber;
        private String sideWayNumber;

        public String getMotorWayNumber() {
            return motorWayNumber;
        }

        public void setMotorWayNumber(String motorWayNumber) {
            this.motorWayNumber = motorWayNumber;
        }

        public String getNonMotorWayNumber() {
            return nonMotorWayNumber;
        }

        public void setNonMotorWayNumber(String nonMotorWayNumber) {
            this.nonMotorWayNumber = nonMotorWayNumber;
        }

        public String getSideWayNumber() {
            return sideWayNumber;
        }

        public void setSideWayNumber(String sideWayNumber) {
            this.sideWayNumber = sideWayNumber;
        }
    }
}
